package it.pecuswap.backend.business;

import it.pecuswap.backend.delegate.AssUtentiProfiliDelegate;
import it.pecuswap.backend.delegate.ProfiliDelegate;
import it.pecuswap.backend.delegate.UtentiDelegate;
import it.pecuswap.backend.entities.AssUtentiProfili;
import it.pecuswap.backend.entities.Profili;
import it.pecuswap.backend.entities.StatiProfili;
import it.pecuswap.backend.entities.Utenti;
import it.pecuswap.backend.exceptions.EntityHomeException;
import it.pecuswap.backend.security.PasswordHash;
import it.pecuswap.backend.wrappers.UtentiWrapper;
import it.pecuswap.commons.client.rest.parameters.CompleteRegistrationParameter;
import it.pecuswap.commons.dto.UtentiDTO;
import it.pecuswap.commons.exceptions.PecuswapRestException;

import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.HashSet;
import java.util.List;

import org.apache.log4j.Logger;

public class RegistrazioneBusiness {
	
	private static final Logger LOGGER = Logger.getLogger(RegistrazioneBusiness.class);
	
	public boolean existUsername(String userName) throws EntityHomeException{
		UtentiDelegate delegate = new UtentiDelegate(Utenti.class, false);
		Utenti example = new Utenti();
	    example.setUsername(userName);
	    List<Utenti> user = delegate.findByExample(example);
	    if (user.size() > 0){
	    	return true;
	    } else{
	    	return false;
	    }
	}
	
	public long registerUser(UtentiDTO utenteDTO) throws PecuswapRestException, EntityHomeException {

		UtentiDelegate utentiDelegate = new UtentiDelegate(Utenti.class, true);
		Utenti utente = UtentiWrapper.copyFromDTO(utenteDTO);
		
		try {
			//FIXME: hashing eseguito qui solo se i servizi rest sono protetti da https altrimenti va
			//spostato a frontend
			String hashedPwd = PasswordHash.createHash(utente.getPassword());
			utente.setPassword(hashedPwd);
		} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
			LOGGER.error("Problema durante l'hashing della password.", e);
			throw new PecuswapRestException();
		} 
		
		utentiDelegate.beginTransaction();
		
		//FIXME: creo il profilo (solo momentaneamente, il profilo deve arrivare da frontend)
		Profili profilo = new Profili();
		profilo.setRuolo("UTENTE");
		HashSet<Profili> profili = new HashSet<Profili>();
		profili.add(profilo);
		profilo.setStatiProfili(new StatiProfili(1));
		ProfiliDelegate profiliDelegate = new ProfiliDelegate(Profili.class, true);
		profiliDelegate.save(profilo);
		
		utentiDelegate.save(utente);
		
		AssUtentiProfili aup = new AssUtentiProfili();
		aup.setProfili(profilo);
		aup.setUtenti(utente);
		AssUtentiProfiliDelegate aupDelegate = new AssUtentiProfiliDelegate(AssUtentiProfili.class, true);
		aupDelegate.save(aup);
		HashSet<AssUtentiProfili> profilis = new HashSet<AssUtentiProfili>();
		profilis.add(aup);
		utente.setAssUtentiProfilis(profilis);
		
		utentiDelegate.closeTransaction();
		
		return utente.getIdUtente();
	}

	public void completeRegistration(CompleteRegistrationParameter param) 
			throws PecuswapRestException, EntityHomeException {
		
		UtentiDelegate utentiDelegate = new UtentiDelegate(Utenti.class, true);
		Utenti utenteExample = new Utenti();
		utenteExample.setTokenIscrizione(param.getTokenRegistrazione());
		utenteExample.setIdUtente(param.getIdUtente());
		
		List<Utenti> utentiTrovati = utentiDelegate.findByExample(utenteExample);
		if (utentiTrovati.size() == 1){
			//procedo con la registrazione
			utentiDelegate.beginTransaction();
			
			Utenti utente = utentiTrovati.get(0);
			utentiDelegate.update(utente);

			utentiDelegate.closeTransaction();
		} else {
			throw new PecuswapRestException();
		}
	}

}
